﻿using PrototypePattern.AppExample;
using System;

namespace PrototypePattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello PrototypePattern!");

            {
                // 通用克隆
                ConcretePrototype prototype = new ConcretePrototype();
                ConcretePrototype copy = (ConcretePrototype)prototype.Clone();
            }

            {
                // MemberwiseClone 浅克隆
                ConcretePrototypeA prototype = new ConcretePrototypeA();
                ConcretePrototypeA copy = prototype.Clone();
                Console.WriteLine($"对象比较=>{prototype == copy}, 对象属性比较=>{prototype.MyMember == copy.MyMember}。");
            }

            {
                // ICloneable 深克隆
                ConcretePrototypeB prototype = new ConcretePrototypeB();
                ConcretePrototypeB copy = (ConcretePrototypeB)prototype.Clone();
                Console.WriteLine($"对象比较=>{prototype == copy}, 对象属性比较=>{prototype.MyMember == copy.MyMember}。");
            }

            {
                // Serializable 序列化实现深克隆
                WeeklyLog log_previous = new WeeklyLog();
                Attachment attachment = new Attachment();
                log_previous.Attachment = attachment;
                WeeklyLog log_new = log_previous.Clone();
                Console.WriteLine("周报是否相同？{0}", (log_previous == log_new) ? "是" : "否");
                Console.WriteLine("附件是否相同？{0}", (log_previous.Attachment == log_new.Attachment) ? "是" : "否");
            }

            {
                // 原型管理器-PrototypeManager
                PrototypeManager pm = PrototypeManager.CreateSingleProfitObj(); // 单例模式构建
                pm.Add("C", new ConcretePrototypeC());
                pm.Add("D", new ConcretePrototypeD());
                Console.WriteLine("1.对象比较是否相同？{0}", (pm.Get("C") == pm.Get("D")) ? "是" : "否");
                Console.WriteLine("2.对象比较是否相同？{0}", (pm.Get("D") == pm.Get("D")) ? "是" : "否");
            }

            Console.ReadKey();
        }
    }

    #region PrototypePattern-Demo-浅克隆（通用）
    abstract class Prototype 
    {
        public abstract Prototype Clone();
    }

    class ConcretePrototype : Prototype
    {
        /// <summary>
        /// 成员变量
        /// </summary>
        public string Attr { get; set; }

        /// <summary>
        /// 克隆方法，通过赋值的方式来实现对象的复制。
        /// </summary>
        /// <returns></returns>
        public override Prototype Clone() => new ConcretePrototype
        {
            Attr = Attr //成员变量赋值
        };
    }
    #endregion

    #region PrototypePattern-Demo-MemberwiseClone
    class Member { }

    class ConcretePrototypeA 
    {
        /// <summary>
        /// 成员变量
        /// </summary>
        public Member MyMember { get; set; }

        /// <summary>
        /// 克隆方法，通过赋值的方式来实现对象的复制。
        /// </summary>
        /// <returns></returns>
        public ConcretePrototypeA Clone() => (ConcretePrototypeA)this.MemberwiseClone(); //浅克隆
        
    }
    #endregion

    #region PrototypePattern-Demo-ICloneable
    class ConcretePrototypeB : ICloneable
    {
        /// <summary>
        /// 成员变量
        /// </summary>
        public Member MyMember { get; set; }

        /// <summary>
        /// 实现深克隆
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            //ConcretePrototypeB copy = (ConcretePrototypeB)this.MemberwiseClone();
            ConcretePrototypeB copy = this.MemberwiseClone() as ConcretePrototypeB; //对象转化，同上等效
            Member newMember = new Member();
            copy.MyMember = newMember;
            return copy;
        }
    }
    #endregion

}
